/*
 * Copyright (C) 2015-2016  Nicola Spanti (RyDroid) <dev@nicola-spanti.info>
 * 
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License for more details.
 * 
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
 */


#include "PlanetWars2dRT-core/utils/cstring_functions.h"
#include <stdlib.h>
#include <ctype.h>


EXTERN_C_BEGIN


bool
cstring_equals(const char* str1,
	       const char* str2)
{
  return strcmp(str1, str2) == 0;
}

bool
cstring_starts_with(const char* a_string,
		    const char* potential_prefix)
{
  return strstr(a_string, potential_prefix) == a_string;
}

bool
cstring_ends_with(const char* base,
		  const char* str)
{
    unsigned int blen = strlen(base);
    unsigned int slen = strlen(str);
    return blen >= slen && strcmp(base + blen - slen, str) == 0;
}

void
reverse_cstring(char* a_string)
{
  size_t length = strlen(a_string);
  size_t half_length = length / 2;
  size_t i = 0;
  
  while(i < half_length)
    {
      char tmp = a_string[i];
      a_string[i] = a_string[length - i -1];
      a_string[length - i -1] = tmp;
      ++i;
    }
}

char*
get_strcpy(const char* a_string)
{
  if(a_string == NULL)
    {
      return NULL;
    }
  
  char* new_string = (char*) malloc(sizeof(char) * (strlen(a_string) +1));
  strcpy(new_string, a_string);
  return new_string;
}

char*
get_reverse_cstring(const char* a_string)
{
  char* string_reversed = get_strcpy(a_string);
  reverse_cstring(string_reversed);
  return string_reversed;
}

void
cstring_ltrim(char* a_string,
	      char character_to_strip)
{
  if(a_string != NULL)
    {
      while(*a_string == character_to_strip)
	{
	  strcpy(a_string, a_string + 1);
	}
    }
}

void
cstring_rtrim(char* a_string,
	      char character_to_strip)
{
  if(a_string != NULL)
    {
      a_string += strlen(a_string) -1;
      while(*a_string == character_to_strip)
	{
	  *a_string = '\0';
	  --a_string;
	}
    }
}

void
cstring_trim(char* a_string,
	     char character_to_strip)
{
  cstring_ltrim(a_string, character_to_strip);
  cstring_rtrim(a_string, character_to_strip);
}

void
cstring_trim_new_line(char* a_string)
{
  cstring_trim(a_string, '\n');
  cstring_trim(a_string, '\r');
}

bool
cstring_contains_unsafe(const char* a_string,
			char character)
{
  while(*a_string)
    {
      if(*a_string == character)
	{
	  return true;
	}
      ++a_string;
    }
  return false;
}

bool
cstring_contains(const char* a_string,
		 char character)
{
  return
    a_string == NULL
    ? false
    : cstring_contains_unsafe(a_string, character);
}

size_t
get_nb_of_character_of_cstring(const char* a_string,
			       char character)
{
  if(a_string == NULL)
    {
      return 0;
    }
  
  size_t nb = 0;
  while(*a_string)
    {
      if(*a_string == character)
	{
	  ++nb;
	}
      ++a_string;
    }
  return nb;
}

void
cstring_tolower(char* a_string)
{
  if(a_string != NULL)
    {
      while(*a_string)
	{
	  *a_string = tolower(*a_string);
	  ++a_string;
	}
    }
}

void
cstring_toupper(char* a_string)
{
  if(a_string != NULL)
    {
      while(*a_string)
	{
	  *a_string = toupper(*a_string);
	  ++a_string;
	}
    }
}

bool
cstring_contains_only_digits(const char* a_string)
{
  if(a_string == NULL)
    {
      return false;
    }
  
  while(*a_string)
    {
      if(!isdigit(*a_string))
	{
	  return false;
	}
      ++a_string;
    }
  return true;
}

bool
cstring_is_int_trimed(const char* a_string)
{
  return
    a_string != NULL &&
    (*a_string == '+' || *a_string == '-'  ||
     isdigit(*a_string))
    &&
    cstring_contains_only_digits(++a_string);
}

bool
cstring_is_int(const char* a_string)
{
  return
    a_string != NULL &&
    (*a_string == ' ' || *a_string == '\t' ||
     *a_string == '+' || *a_string == '-'  ||
     isdigit(*a_string))
    &&
    cstring_contains_only_digits(++a_string);
}

bool
cstring_is_uint_trimed(const char* a_string)
{
  return
    a_string != NULL &&
    (*a_string == '+' || isdigit(*a_string)) &&
    cstring_contains_only_digits(++a_string);
}

bool
cstring_is_uint(const char* a_string)
{
  return
    a_string != NULL &&
    (*a_string == ' ' || *a_string == '\t' ||
     *a_string == '+' || isdigit(*a_string))
    &&
    cstring_contains_only_digits(++a_string);
}


EXTERN_C_END
